struct MyListNode
{
    int _val;
    MyListNode* _next;

    MyListNode(int val = 0)
        :_val(val)
        , _next(nullptr)
    {}
};

class MyLinkedList {
public:
    MyLinkedList()
        :_head(nullptr)
        , _size(0)
    {}

    int get(int index) {
        if (index < 0 || index >= _size)
            return -1;

        MyListNode* cur = _head;
        while (index--)
        {
            cur = cur->_next;
        }

        return cur->_val;
    }

    void addAtHead(int val) {
        MyListNode* newNode = new MyListNode(val);
        newNode->_next = _head;
        _head = newNode;
        ++_size;
    }

    void addAtTail(int val) {
        MyListNode* newNode = new MyListNode(val);
        if (_head == nullptr)
            _head = newNode;
        else
        {
            MyListNode* cur = _head;
            while (cur->_next)
            {
                cur = cur->_next;
            }
            cur->_next = newNode;
        }
        ++_size;
    }

    void addAtIndex(int index, int val) {
        if (index == 0)
        {
            addAtHead(val);
        }
        else if (index == _size)
        {
            addAtTail(val);
        }
        else if (index > 0 && index < _size)
        {
            MyListNode* newNode = new MyListNode(val);
            MyListNode* cur = _head;
            while (--index)
            {
                cur = cur->_next;
            }
            newNode->_next = cur->_next;
            cur->_next = newNode;
            ++_size;
        }
    }

    void deleteAtIndex(int index) {
        if (index == 0)
        {
            MyListNode* del = _head;
            _head = _head->_next;
            delete del;
            --_size;
        }
        else if (index > 0 && index < _size)
        {
            MyListNode* cur = _head;
            while (--index)
            {
                cur = cur->_next;
            }
            MyListNode* del = cur->_next;
            cur->_next = del->_next;
            delete del;
            --_size;
        }
    }
private:
    MyListNode* _head;
    size_t _size;
};